<template>
	<view class="chart-container">
		<!-- 小程序使用 canvas 组件 -->
		<canvas
			v-if="!isH5"
			:id="canvasId"
			:canvas-id="canvasId"
			class="echarts-canvas"
			:style="{ width: '100%', height: '100%' }" />
		<!-- H5 使用普通 div -->
		<div v-else ref="chart" class="echarts-dom"></div>
	</view>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from "vue";
import * as echarts from "echarts/core";
import { LineChart, BarChart } from "echarts/charts";
import {
	TitleComponent,
	TooltipComponent,
	GridComponent,
	DatasetComponent,
} from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
import type { ECharts, EChartsOption } from "echarts";
const isH5 = process.env.UNI_PLATFORM === "h5";
const isApp = process.env.UNI_PLATFORM === "app";
const isMp = process.env.UNI_PLATFORM?.startsWith("mp-");
const canvasId = `ec-${Date.now()}`;
// 注册必须的组件
echarts.use([
	TitleComponent,
	TooltipComponent,
	GridComponent,
	DatasetComponent,
	LineChart,
	BarChart,
	CanvasRenderer,
]);

interface Props {
	options: EChartsOption;
}

const props = defineProps<Props>();

const chart = ref<HTMLElement | null>(null);
const chartInstance: any = ref<ECharts | null>(null);
const initMpChart = (): Promise<void> => {
	return new Promise((resolve) => {
		// 小程序使用 uni-app 的 canvas 组件
		chartInstance.value = echarts.init({
			id: canvasId,
			canvas: null,
			type: "2d",
			width: uni.getSystemInfoSync().windowWidth,
			height: 300,
			pixelRatio: uni.getSystemInfoSync().pixelRatio,
		});
		resolve();
	});
};
const initAppChart = (): Promise<void> => {
	return new Promise((resolve, reject) => {
		const query = uni.createSelectorQuery();
		query
			.select(`#${canvasId}`)
			.fields({ node: true, size: true })
			.exec((res) => {
				if (!res[0]?.node) {
					reject(new Error("Canvas 节点未找到"));
					return;
				}

				const canvasNode = res[0].node;
				const dpr = uni.getSystemInfoSync().pixelRatio || 1;

				try {
					// App 端直接初始化，不需要 getContext
					chartInstance.value = echarts.init(canvasNode, null, {
						width: res[0].width,
						height: res[0].height,
						devicePixelRatio: dpr,
					});

					resolve();
				} catch (error) {
					console.error("App端初始化详细错误:", error);
					reject(error);
				}
			});
	});
};
const initChart = async () => {
	try {
		if (isH5) {
			// H5 环境 - 原有逻辑
			if (!chart.value) return;
			chartInstance.value = echarts.init(chart.value, null, {
				renderer: "canvas",
				devicePixelRatio: window.devicePixelRatio || 1,
			});
		}
		// #ifdef APP-PLUS
		else if (isApp) {
			// App 环境特殊处理
			await initAppChart();
		}
		// #endif
		else {
			// 小程序环境
			await initMpChart();
		}

		chartInstance.value?.setOption(props.options);
	} catch (err) {
		console.error("图表初始化失败:", err);
	}
};
const setupResizeHandler = () => {
	if (isH5) {
		const handleResize = () => {
			chartInstance.value?.resize();
		};

		window.addEventListener("resize", handleResize, { passive: true });
		return () => {
			window.removeEventListener("resize", handleResize);
		};
	}
	// #ifdef APP-PLUS || MP-WEIXIN
	else {
		// App和小程序使用 uni 的 resize 事件
		const handleResize = () => {
			chartInstance.value?.resize();
		};

		uni.onWindowResize(handleResize);
		return () => {
			uni.offWindowResize(handleResize);
		};
	}
	// #endif
};
const generateOptionId = (length = 23): string => {
	return Number(
		Math.random()
			.toString()
			.substring(3, length + 3) + Date.now()
	).toString(length);
};
onMounted(() => {
	props.options.id = generateOptionId();
	initChart();
	// 添加resize监听
	if (isH5) {
		window.addEventListener("resize", handleResize, { passive: true });
	} else {
		uni.onWindowResize(handleResize);
	}
});

const cleanup = setupResizeHandler();
const handleResize = () => {
	chartInstance.value?.resize();
};
onBeforeUnmount(() => {
	cleanup();
	// chartInstance.value?.dispose();
	if (isH5) {
		window.removeEventListener("resize", handleResize);
	} else {
		uni.offWindowResize(handleResize);
	}
	chartInstance.value?.dispose();
});
watch(
	() => props.options,
	(newVal) => {
		nextTick(() => {
			chartInstance.value?.setOption(newVal);
		});
	},
	{ deep: true }
);
</script>

<style scoped>
/* 根据需要添加样式 */
.chart-container {
	width: 100%;
	height: 30vh;
	position: relative;
}

.echarts-canvas,
.echarts-dom {
	width: 100%;
	height: 30vh;
}

/* 小程序需要额外样式 */
canvas {
	display: block;
}
/* App端需要绝对定位 */
/* #ifdef APP-PLUS */
.echarts-canvas {
	position: absolute;
	top: 0;
	left: 0;
}
/* #endif */
</style>
